home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / Kibitz / AppleEvents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-06  |  8.9 KB  |  354 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        appleevents.c
  5. ** Written by:  Keith Rollin
  6. **
  7. ** Copyright © 1990-1994 Apple Computer, Inc.
  8. ** All rights reserved.
  9. **
  10. ** This code is completely based on the great work done by Keith Rollin.
  11. ** All I did was to add more comments than _anybody_ would want, make some
  12. ** things a little more general, and to set the code up so the the custom
  13. ** events are handled in a separate file. */
  14.  
  15.  
  16.  
  17. /*****************************************************************************/
  18.  
  19.  
  20.  
  21. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  22. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  23. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  24.  
  25. #ifndef __AEUTILS__
  26. #include <AEUtils.h>
  27. #endif
  28.  
  29. #ifndef __GESTALTEQU__
  30. #include <GestaltEqu.h>
  31. #endif
  32.  
  33. #ifndef __UTILITIES__
  34. #include <Utilities.h>
  35. #endif
  36.  
  37.  
  38.  
  39. /*****************************************************************************/
  40.  
  41.  
  42.  
  43. #define rErrorAlert 129
  44. #define kTimeOutInTicks (60 * 30)    /* 30 second timeout. */
  45.  
  46.  
  47.  
  48. /*****************************************************************************/
  49.  
  50.  
  51.  
  52. struct triplets{
  53.     AEEventClass        theEventClass;
  54.     AEEventID            theEventID;
  55.     ProcPtr                theHandler;
  56.     AEEventHandlerUPP    theUPP;
  57. };
  58. typedef struct triplets triplets;
  59. static triplets keywordsToInstall[] = {
  60.     { kCoreEventClass,        kAEOpenApplication,        (ProcPtr)KibitzAEOpenApplication,    nil },
  61.     { kCoreEventClass,        kAEOpenDocuments,        (ProcPtr)KibitzAEOpenDocuments,        nil },
  62.     { kCoreEventClass,        kAEPrintDocuments,        (ProcPtr)KibitzAEPrintDocuments,    nil },
  63.     { kCoreEventClass,        kAEQuitApplication,        (ProcPtr)KibitzAEQuitApplication,    nil }
  64.         /* The above are the four required AppleEvents. */
  65. };
  66.  
  67. Boolean        gHasAppleEvents = false;
  68. Boolean        gHasPPCToolbox  = false;
  69.  
  70.  
  71.  
  72. /*****************************************************************************/
  73.  
  74.  
  75.  
  76. extern Boolean    gQuitApplication;
  77. extern Cursor    *gCurrentCursor;
  78. extern short    gPrintPage;
  79.  
  80.  
  81.  
  82. /*****************************************************************************/
  83. /*****************************************************************************/
  84.  
  85.  
  86.  
  87. /* InitAppleEvents
  88. **
  89. ** Intialize our AppleEvent dispatcher table.  For every triplet of entries in
  90. ** keywordsToInstall, we make a call to AEInstallEventHandler(). */
  91.  
  92. #pragma segment AppleEvents
  93. void    InitAppleEvents(void)
  94. {
  95.     OSErr    err;
  96.     long    result;
  97.     short    i;
  98.  
  99.     gHasPPCToolbox  = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  100.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  101.  
  102.     if (gHasAppleEvents) {
  103.         for (i = 0; i < (sizeof(keywordsToInstall) / sizeof(triplets)); ++i) {
  104.  
  105.             if (!keywordsToInstall[i].theUPP)
  106.                 keywordsToInstall[i].theUPP = NewAEEventHandlerProc(keywordsToInstall[i].theHandler);
  107.  
  108.             err = AEInstallEventHandler(
  109.                 keywordsToInstall[i].theEventClass,    /* What class to install.  */
  110.                 keywordsToInstall[i].theEventID,    /* Keywords to install.    */
  111.                 keywordsToInstall[i].theUPP,        /* The AppleEvent handler. */
  112.                 0L,                                    /* Unused refcon.           */
  113.                 false                                /* Only for our app.       */
  114.             );
  115.  
  116.             if (err) {
  117.                 Alert(rErrorAlert, gAlertFilterUPP);
  118.                 return;
  119.             }
  120.         }
  121.     }
  122. }
  123.  
  124.  
  125.  
  126. /*****************************************************************************/
  127. /*****************************************************************************/
  128.  
  129.  
  130.  
  131. #pragma segment AppleEvents
  132. pascal OSErr    KibitzAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  133. {
  134. #ifndef __MWERKS__
  135. #pragma unused (message, refcon)
  136. #endif
  137.  
  138.     OSErr        err;
  139.  
  140.     err = noErr;
  141.  
  142.     gCurrentCursor = nil;
  143.         /* Force re-calc of cursor region and cursor to use. */
  144.  
  145.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  146.         reply,                    /* The AppleEvent.              */
  147.         keyReplyErr,            /* AEKeyword                 */
  148.         typeShortInteger,        /* Desired type.             */
  149.         (Ptr)&err,                /* Pointer to area for data. */ 
  150.         sizeof(short)            /* Size of data area.         */
  151.     );
  152.  
  153.     return(err);
  154. }
  155.  
  156.  
  157.  
  158. /*****************************************************************************/
  159.  
  160.  
  161.  
  162. #pragma segment AppleEvents
  163. pascal OSErr    KibitzAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  164. {
  165. #ifndef __MWERKS__
  166. #pragma unused (refcon)
  167. #endif
  168.  
  169.     OSErr        err;
  170.  
  171.     gCurrentCursor = nil;
  172.         /* Force re-calc of cursor region and cursor to use. */
  173.  
  174.     err = OpenDocEventHandler(message, reply, 0);
  175.  
  176.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  177.         reply,                    /* The AppleEvent.              */
  178.         keyReplyErr,            /* AEKeyword                 */
  179.         typeShortInteger,        /* Desired type.             */
  180.         (Ptr)&err,                /* Pointer to area for data. */ 
  181.         sizeof(short)            /* Size of data area.         */
  182.     );
  183.  
  184.     return(err);
  185. }
  186.  
  187.  
  188.  
  189. /*****************************************************************************/
  190.  
  191.  
  192.  
  193. #pragma segment AppleEvents
  194. pascal OSErr    KibitzAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  195. {
  196. #ifndef __MWERKS__
  197. #pragma unused (refcon)
  198. #endif
  199.  
  200.     OSErr        err;
  201.     short        openMode;
  202.  
  203.     DoSetCursor(&qd.arrow);
  204.  
  205.     openMode = 1;
  206.     if (!AEInteractWithUser(kTimeOutInTicks, nil, nil)) ++openMode;
  207.  
  208.     err = OpenDocEventHandler(message, reply, openMode);
  209.  
  210.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  211.         reply,                    /* The AppleEvent.              */
  212.         keyReplyErr,            /* AEKeyword                 */
  213.         typeShortInteger,        /* Desired type.             */
  214.         (Ptr)&err,                /* Pointer to area for data. */ 
  215.         sizeof(short)            /* Size of data area.         */
  216.     );
  217.  
  218.     return(err);
  219. }
  220.  
  221.  
  222.  
  223. /*****************************************************************************/
  224.  
  225.  
  226.  
  227. #pragma segment AppleEvents
  228. pascal OSErr    KibitzAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  229. {
  230. #ifndef __MWERKS__
  231. #pragma unused (message, refcon)
  232. #endif
  233.  
  234.     OSErr    err;
  235.  
  236.     gCurrentCursor = nil;
  237.         /* Force re-calc of cursor region and cursor to use. */
  238.  
  239.     if (CloseAllWindows()) {
  240.         gQuitApplication = true;
  241.         err = noErr;
  242.     }
  243.     else err = errAEEventNotHandled;
  244.  
  245.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  246.         reply,                    /* The AppleEvent.              */
  247.         keyReplyErr,            /* AEKeyword                 */
  248.         typeShortInteger,        /* Desired type.             */
  249.         (Ptr)&err,                /* Pointer to area for data. */ 
  250.         sizeof(short)            /* Size of data area.         */
  251.     );
  252.  
  253.     return(noErr);
  254. }
  255.  
  256.  
  257.  
  258. /*****************************************************************************/
  259.  
  260.  
  261.  
  262. /* OpenDocEventHandler
  263. **
  264. ** Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments".
  265. ** This routine gets the direct parameter, parses it up into little FSSpecs,
  266. ** and opens each indicated file.  It also shows the technique to be used in
  267. ** determining if you are doing everything the AppleEvent record is telling
  268. ** you.  Parameters can be divided up into two groups: required and optional.
  269. ** Before executing an event, you must make sure that you've read all the
  270. ** required events.  This is done by making an "any more?" call to the
  271. ** AppleEvent manager. */
  272.  
  273. #pragma segment AppleEvents
  274. OSErr    OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode)
  275. {
  276. #ifndef __MWERKS__
  277. #pragma unused (reply)
  278. #endif
  279.  
  280.     OSErr        err;
  281.     OSErr        err2;
  282.     AEDesc        theDesc;
  283.     FSSpec        theFSS;
  284.     short        loop;
  285.     long        numFilesToOpen;
  286.     AEKeyword    ignoredKeyWord;
  287.     DescType    ignoredType;
  288.     Size        ignoredSize;
  289.     FileRecHndl    frHndl;
  290.     WindowPtr    docWindow;
  291.  
  292.     theDesc.dataHandle = nil;
  293.         /* Make sure disposing of the descriptors is okay in all cases.
  294.         ** This will not be necessary after 7.0b3, since the calls that
  295.         ** attempt to create the descriptors will nil automatically
  296.         ** upon failure. */
  297.  
  298.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &theDesc);
  299.     if (err)
  300.         return(err);
  301.  
  302.     if (!MissedAnyParameters(message)) {
  303.  
  304. /* Got all the parameters we need.  Now, go through the direct object,
  305. ** see what type it is, and parse it up. */
  306.  
  307.         err = AECountItems(&theDesc, &numFilesToOpen);
  308.         if (!err) {
  309.             /* We have numFilesToOpen that need opening, as either a window
  310.             ** or to be printed.  Go to it... */
  311.  
  312.             for (loop = 1; ((loop <= numFilesToOpen) && (!err)); ++loop) {
  313.                 err = AEGetNthPtr(        /* GET NEXT IN THE LIST...         */
  314.                     &theDesc,            /* List of file names.             */
  315.                     loop,                /* Item # in the list.             */
  316.                     typeFSS,            /* Item is of type FSSpec.         */
  317.                     &ignoredKeyWord,    /* Returned keyword -- we know.  */
  318.                     &ignoredType,        /* Returned type -- we know.     */
  319.                     (Ptr)&theFSS,        /* Where to put the FSSpec info. */
  320.                     sizeof(theFSS),        /* Size of the FSSpec info.         */
  321.                     &ignoredSize        /* Actual size -- we know.         */
  322.                 );
  323.                 if (err) break;
  324.  
  325.                 err = AppOpenDocument(&frHndl, &theFSS, fsRdWrPerm);
  326.                 if (err) break;
  327.  
  328.                 gPrintPage = mode;
  329.                     /* Open the window off-screen if we are printing. */
  330.                 err = AppNewWindow(frHndl, &docWindow, (WindowPtr)-1);
  331.                 if (err)
  332.                     AppDisposeDocument(frHndl);
  333.                 else {
  334.                     if (gPrintPage) {
  335.                         err  = AppPrintDocument(frHndl, (mode == 2), (loop == 1));
  336.                         mode = 1;
  337.                         AppDisposeDocument(frHndl);
  338.                         DisposeAnyWindow(docWindow);
  339.                     }
  340.                     else AppAutoLaunch(frHndl);
  341.                 }
  342.                 gPrintPage = 0;
  343.             }
  344.         }
  345.     }
  346.     AppPrintDocument(nil, false, false);    /* Clean up after printing, if we did any. */
  347.  
  348.     err2 = AEDisposeDesc(&theDesc);
  349.     return(err ? err : err2);
  350. }
  351.  
  352.  
  353.  
  354.